//This program is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program.  If not, see <http://www.gnu.org/licenses/>.

#include "tachometerui.h"
#include "ui_tachometerui.h"
#include <typeinfo>

ProzessLeitSystem * ProzessLeitSystem::instanze = NULL;

ProzessLeitSystem::ProzessLeitSystem(QWidget *parent)
    : QDialog(parent), ui(new Ui::TachometeruiClass)
{
    instanze = this;
    ui->setupUi(this);
    QWidget *toExpand = new QWidget;
    ui->tachoScrollArea->setWidget(toExpand);
    tachoLayout = new QVBoxLayout(toExpand);
    toExpand = new QWidget;
    ui->robotScrollArea->setWidget(toExpand);
    robotLayout = new QVBoxLayout(toExpand);

    camera = new Camera(this);
    camera->setLogTextEdit(ui->cameraLogTextEdit);
    camera->setStateLabel(ui->cameraStateLabel);
    if (settings.contains("settings/cameraHost")) {
        QString host = settings.value("settings/cameraHost").toString();
        quint16 port = settings.value("settings/cameraPort").toInt();
        ui->cameraHostLineEdit->setText(host);
        ui->cameraPortSpinBox->setValue(port);
        camera->setHost(host);
        camera->setPort(port);
        ui->hostname->setText(camera->toString());
        camera->connectToHost();
    }

    canGateway = new CanGateway(this);
    canGateway->setLogTextEdit(ui->cameraLogTextEdit);
    canGateway->setStateLabel(ui->canStateLabel);
    if (settings.contains("settings/canHost")) {
        QString host = settings.value("settings/canHost").toString();
        quint16 port = settings.value("settings/canPort").toInt();
        ui->canHostLineEdit->setText(host);
        ui->canPortSpinBox->setValue(port);
        canGateway->setHost(host);
        canGateway->setPort(port);
        ui->hostname_can->setText(canGateway->toString());
        canGateway->connectToHost();
    }

    if (settings.contains("settings/tachoNumber"))
    {
        int tachoNumber = settings.value("settings/tachoNumber").toInt();
        for (int i = 0; i < tachoNumber; i++)
        {
            quint16 baseid = settings.value(tr("settings/tachoBaseID%1").arg(i)).toInt();
            addTachometer(baseid, canGateway);
        }
    }
    if (settings.contains("settings/robotNumber"))
    {
        int robotNumber = settings.value("settings/robotNumber").toInt();
        for (int i = 0; i < robotNumber; i++)
        {
            QString host = settings.value(tr("settings/robotHost%1").arg(i)).toString();
            quint16 port = settings.value(tr("settings/robotPort%1").arg(i)).toInt();
            quint16 id =  settings.value(tr("settings/robotId%1").arg(i)).toInt();
            QString color =  settings.value(tr("settings/robotColor%1").arg(i)).toString();
            addRobot(id, host, port, &QColor(color));
        }
    }

    QWidget *cameraWidget = new CameraWidget(camera, robotLayout, this);
    ui->cameraScrollArea->setWidget(cameraWidget);
}

ProzessLeitSystem::~ProzessLeitSystem()
{
    TachometerWidget *tacho;
    int tachoNumber = 0;
    for (int i = 0; i < tachoLayout->count(); i++)
    {
        if (tachoLayout->itemAt(i)->widget())
        {
            tacho = dynamic_cast<TachometerWidget*> (tachoLayout->itemAt(i)->widget());
            if (tacho)
            {
                settings.setValue(tr("settings/tachoBaseID%1").arg(tachoNumber), tacho->getBaseID());
                tachoNumber++;
            }
        }
    }
    settings.setValue("settings/tachoNumber", tachoNumber);

    RobotWidget *robotWidget;
    int robotNumber = 0;
    for (int i = 0; i < robotLayout->count(); i++)
    {
        if (robotLayout->itemAt(i)->widget())
        {
            robotWidget = dynamic_cast<RobotWidget*> (robotLayout->itemAt(i)->widget());
            if (robotWidget)
            {
                settings.setValue(tr("settings/robotHost%1").arg(robotNumber), robotWidget->getRobot()->getHost());
                settings.setValue(tr("settings/robotPort%1").arg(robotNumber), robotWidget->getRobot()->getPort());
                settings.setValue(tr("settings/robotId%1").arg(robotNumber), robotWidget->getRobot()->getId());
                settings.setValue(tr("settings/robotColor%1").arg(robotNumber), robotWidget->getRobot()->getColor()->name());
                robotNumber++;
            }
        }
    }
    settings.setValue("settings/robotNumber", robotNumber);

    settings.setValue(tr("settings/cameraHost"), camera->getHost());
    settings.setValue(tr("settings/cameraPort"), camera->getPort());

    settings.setValue(tr("settings/canHost"), canGateway->getHost());
    settings.setValue(tr("settings/canPort"), canGateway->getPort());

    delete ui;
}

void ProzessLeitSystem::on_addTacho_clicked()
{
    addTachometer(ui->tachoBaseIDSpinBox->value(), canGateway);
}

void ProzessLeitSystem::on_addRobot_clicked()
{
    addRobot(ui->robotIDSpinBox->value(), ui->robotHostLineEdit->text(), ui->robotPortSpinBox->value());
}

void ProzessLeitSystem::addTachometer(quint16 baseid, CanGateway * canGateway)
{
    TachometerWidget *widget = new TachometerWidget(baseid, canGateway, this);
    widget->setLogTextEdit(ui->tachoLogTextEdit);
    tachoLayout->addWidget(widget);
}

void ProzessLeitSystem::addRobot(quint16 id, QString host, quint16 port, QColor *color)
{
    RobotWidget *widget = new RobotWidget(id, host, port, camera, color, this);
    widget->setLogTextEdit(ui->robotLogTextEdit);
    robotLayout->addWidget(widget);
}

void ProzessLeitSystem::on_cameraReconnectButton_clicked()
{
    camera->setHost(ui->cameraHostLineEdit->text());
    camera->setPort(ui->cameraPortSpinBox->value());
    ui->hostname->setText(camera->toString());
    camera->connectToHost();
    //camera->sendRequest();
}

void ProzessLeitSystem::on_canReconnectButton_clicked()
{
    canGateway->setHost(ui->canHostLineEdit->text());
    canGateway->setPort(ui->canPortSpinBox->value());
    ui->hostname_can->setText(canGateway->toString());
    canGateway->connectToHost();
}

void ProzessLeitSystem::on_pushButton_clicked()
{
   can_t t;

   t.msgtype   = 'M';
   t.format    = 'S';
   t.id        = SocketBase::_htonl(ui->canID_spinBox->value());
   t.num       = ui->canLengthSpinBox->value();
   QSpinBox * spiner[5] = {ui->canB00spinBox, ui->canB01spinBox, ui->canB02spinBox, ui->canB03spinBox, ui->canB04spinBox};
   for(int i = 0; i < t.num; ++i)
       t.data[i] = spiner[i]->value();
   canGateway->send(t);
}

bool ProzessLeitSystem::camLogCheckBox()
{
    return ui->camLogCheckBox->isChecked();
}
bool ProzessLeitSystem::canLogCheckBox()
{
    return ui->canLogCheckBox->isChecked();
}
